package org.ibase4j.generate;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;

import net.sf.json.JSONArray;
import top.ibase4j.core.util.DataUtil;

public class CustomerTemplateEngine extends VelocityTemplateEngine {
	private static final Logger logger = LoggerFactory.getLogger(CustomerTemplateEngine.class);
//	private VelocityEngine velocityEngine;
//	
//	@Override
//    public CustomerTemplateEngine init(ConfigBuilder configBuilder) {
//		 super.init(configBuilder);
//        if (null == velocityEngine) {
//            Properties p = new Properties();
//            p.setProperty(ConstVal.VM_LOADPATH_KEY, ConstVal.VM_LOADPATH_VALUE);
//            p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "");
//            p.setProperty(Velocity.ENCODING_DEFAULT, ConstVal.UTF8);
//            p.setProperty(Velocity.INPUT_ENCODING, ConstVal.UTF8);
//            p.setProperty("file.resource.loader.unicode", "true");
//            velocityEngine = new VelocityEngine(p);
//        }
//        return this;
//    }
	
	/**
     * <p>
     * 输出 java xml 文件
     * </p>
     */
	@Override
    public AbstractTemplateEngine batchOutput() {
        try {
            List<TableInfo> tableInfoList = this.getConfigBuilder().getTableInfoList();
            for (TableInfo tableInfo : tableInfoList) {
            	logger.debug("tableInfo: " + JSONArray.fromObject(tableInfo).toString());
                Map<String, Object> objectMap = this.getObjectMap(tableInfo);
                Map<String, String> pathInfo = this.getConfigBuilder().getPathInfo();
                CustomerTemplateConfig template = (CustomerTemplateConfig)this.getConfigBuilder().getTemplate();
                CustomerGlobalConfig globalConfig = (CustomerGlobalConfig)this.getConfigBuilder().getGlobalConfig();
                // 自定义内容
                InjectionConfig injectionConfig = this.getConfigBuilder().getInjectionConfig();
                if (null != injectionConfig) {
                    injectionConfig.initMap();
                    objectMap.put("cfg", injectionConfig.getMap());
                    List<FileOutConfig> focList = injectionConfig.getFileOutConfigList();
                    if (CollectionUtils.isNotEmpty(focList)) {
                        for (FileOutConfig foc : focList) {
                            if (this.isCreate(foc.outputFile(tableInfo))) {
                                this.writer(objectMap, foc.getTemplatePath(), foc.outputFile(tableInfo));
                            }
                        }
                    }
                }
                // Mp.java
                String entityName = tableInfo.getEntityName();
                if (null != entityName && null != pathInfo.get(ConstVal.ENTITY_PATH)) {
                    String entityFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + File.separator + "%s" + this.suffixJavaOrKt()), entityName);
                    if (this.isCreate(entityFile)) {
                        this.writer(objectMap, this.templateFilePath(template.getEntity(this.getConfigBuilder().getGlobalConfig().isKotlin())), entityFile);
                    }
                }
                // MpMapper.java
                if (null != tableInfo.getMapperName() && null != pathInfo.get(ConstVal.MAPPER_PATH)) {
                    String mapperFile = String.format((pathInfo.get(ConstVal.MAPPER_PATH) + File.separator + tableInfo.getMapperName() + this.suffixJavaOrKt()), entityName);
                    if (this.isCreate(mapperFile)) {
                        this.writer(objectMap, this.templateFilePath(template.getMapper()), mapperFile);
                    }
                }
                // MpMapper.xml
                if (null != tableInfo.getXmlName() && null != pathInfo.get(ConstVal.XML_PATH)) {
                    String xmlFile = String.format((pathInfo.get(ConstVal.XML_PATH) + File.separator + tableInfo.getXmlName() + ConstVal.XML_SUFFIX), entityName);
                    if (this.isCreate(xmlFile)) {
                        this.writer(objectMap, this.templateFilePath(template.getXml()), xmlFile);
                    }
                }
                // IMpService.java
                if (null != tableInfo.getServiceName() && null != pathInfo.get(ConstVal.SERVICE_PATH)) {
                    String serviceFile = String.format((pathInfo.get(ConstVal.SERVICE_PATH) + File.separator + tableInfo.getServiceName() + this.suffixJavaOrKt()), entityName);
                    if (this.isCreate(serviceFile)) {
                        this.writer(objectMap, this.templateFilePath(template.getService()), serviceFile);
                    }
                }
                // MpServiceImpl.java
                if (null != tableInfo.getServiceImplName() && null != pathInfo.get(ConstVal.SERVICEIMPL_PATH)) {
                    String implFile = String.format((pathInfo.get(ConstVal.SERVICEIMPL_PATH) + File.separator + tableInfo.getServiceImplName() + this.suffixJavaOrKt()), entityName);
                    if (this.isCreate(implFile)) {
                        this.writer(objectMap, this.templateFilePath(template.getServiceImpl()), implFile);
                    }
                }
                
                logger.debug("自定义生产html和js文件");
                // .html
                String htmlFile = globalConfig.getHtmlOutputDir() + File.separator + tableInfo.getName() + ".html";
                if (DataUtil.isNotEmpty(globalConfig.getHtmlOutputDir()) && this.isCreate(htmlFile)) {
                	objectMap.put("controllerBaseMapping", (new StringBuilder("/")).append(Character.toLowerCase(entityName.charAt(0))).append(entityName.substring(1)).toString());
                    this.writer(objectMap, this.templateFilePath(template.getHtml()), htmlFile);
                }
                // .js
                String jsFile = globalConfig.getJsOutputDir() + File.separator + tableInfo.getName() + ".js";
                if (DataUtil.isNotEmpty(globalConfig.getJsOutputDir()) && this.isCreate(jsFile)) {
                	objectMap.put("controllerBaseMapping", (new StringBuilder("/")).append(Character.toLowerCase(entityName.charAt(0))).append(entityName.substring(1)).toString());
                    this.writer(objectMap, this.templateFilePath(template.getJs()), jsFile);
                }
                
            }
        } catch (Exception e) {
            logger.error("无法创建文件，请检查配置信息！", e);
        }
        return this;
    }
}
